package com.szdtoo.aspect;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.szdtoo.annotation.SystemLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

@Aspect
public class SystemLogAspect {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(com.szdtoo.annotation.SystemLog)")
    public void pointCut() {}

    @Before("pointCut()")
    public void processBefore(JoinPoint joinPoint) {
        saveSystemLogBefore(joinPoint);
    }

    @Around("pointCut()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        Long beginTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        Long endTime = System.currentTimeMillis();
        Long time = endTime - beginTime;
        saveSystemLogAround(time);
        return result;
    }

    /**
     * 统计方法描述，入参
     * @param joinPoint
     */
    public void saveSystemLogBefore(JoinPoint joinPoint) {
        //注解描述
        String operation = null;

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SystemLog systemLog = method.getAnnotation(com.szdtoo.annotation.SystemLog.class);
        if(systemLog != null) {
            operation = systemLog.value();
        }
        //请求的类名和方法名和入参
        String methodClassName = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();
        String params = null;
        if(args != null) {
            List<Object> list = Arrays.asList(args);
            params = JSONObject.toJSONString(list);
        }

        logger.info("参数:{"+params+"}, 方法描述:{"+operation+"}, 方法名:{}.{}",methodClassName,methodName);
    }

    /**
     * 统计方法耗时
     * @param time
     */
    public void saveSystemLogAround(Long time) {
        logger.info("该方法耗时:{}ms", time);
    }
}
